
#ifndef SX_FIXED_TIMELINE_CURVE_CONTROLLER_H
#define SX_FIXED_TIMELINE_CURVE_CONTROLLER_H

#include <sxFixedTimelineController.h>
#include <sxBezierEditController.h>

using Sx::Interface::ViewportController;
using Sx::Interface::Viewport;
using Sx::Interface::Canvas;
using Sx::Interface::MouseButton;
using Sx::Interface::ModifierKey;
using Sx::Interface::ScenePickingController;
using Sx::Interface::BezierEditController;

namespace Sx {
namespace Multimedia {
namespace Interface {

/* 
 * This controller can be used to provide the data-points of a Bezier curve for
 * any purpose.
 */
class FixedTimelineCurveController : public ViewportController, public FixedTimeline {
public:
	FixedTimelineCurveController(Viewport* viewport,
		const std::shared_ptr<Canvas>& canvas, 
		const std::shared_ptr<ScenePickingController>& pickingController, 
		const std::shared_ptr<RendererImplementation>& cameraRenderer, 
		const std::shared_ptr<RendererImplementation>& plotRenderer,
		const std::shared_ptr<RendererImplementation>& cuboidRenderer,
		const std::shared_ptr<RendererImplementation>& bezierRenderer);
	virtual ~FixedTimelineCurveController();

	/* Viewport Controller Interface */
	bool initialize();
	void update(float dt);
	void render() const;

	void resize(int width, int height);

	/* Pass-Through Interface for FixedTimelineController */
	void setInputEnabled(bool enabled);
	bool setDivisions(unsigned int count);

	bool setCurrentTime(unsigned int time);
	bool incrementTime();
	bool decrementTime();
	bool setCurrentFrame(unsigned int frame);
	bool setEndTime(unsigned int endTime);
	bool setFrameCount(unsigned int frameCount);

	unsigned int getCurrentTime() const;
	unsigned int getStartTime() const;
	unsigned int getEndTime() const;

	unsigned int size() const;

	/* Replayable */
	void setReplayable(const std::shared_ptr<Replayable>& replayable);

	/* Curve Information */
	bool getCurveApproximation(Util::ArrayList<Eigen::Vector3f>& approximationPoints);

	long getEndPointSnapPositionX(bool index) const;
	long getEndPointSnapPositionY(bool index) const;
	long getEndPointSnapPositionZ(bool index) const;

	/* Mouse Events */
	void mousePressEvent(int x, int y, MouseButton button, ModifierKey modifierKey);
	void mouseReleaseEvent(int x, int y, MouseButton button, ModifierKey modifierKey);
	void mouseClickEvent(int x, int y, MouseButton button, ModifierKey modifierKey);
	void mouseMoveEvent(int x, int y, MouseButton button, ModifierKey modifierKey);
	void mouseWheelEvent(int delta);
	void mouseEnterEvent();
	void mouseExitEvent();

protected:
	std::shared_ptr<FixedTimelineController> timeline;
	std::shared_ptr<BezierEditController> curveEditor;
};

}

}

}

#endif
